import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import { isScrollBarVisible } from '../../utils/utility';
import { Icon } from '../icon';
import { Input } from '../input';

export type OptionValues = string;

export type Options<TValue = OptionValues> = Array<IOption<TValue>>;

export interface IOption<TValue = OptionValues> {
  /** Text for rendering */
  label?: string;
  /** Value for searching */
  value?: TValue;
  disabled?: boolean;
}

export interface IDropdownListProps {
  emptyTips?: React.ReactNode;
  onFilterChange: (text: string) => void;
  options: Options;
  onInputClick: (e: React.MouseEvent<HTMLInputElement | HTMLDivElement>) => void;
  onItemClick: (option: IOption, index: number) => void;
  value: IOption[];
  type: string;
}

export class DropdownList extends React.Component<IDropdownListProps, {}> {
  public static propTypes = {
    emptyTips: PropTypes.node,
    onFilterChange: PropTypes.func.isRequired,
    onInputClick: PropTypes.func.isRequired,
    onItemClick: PropTypes.func.isRequired,
    type: PropTypes.string.isRequired,
  };
  public componentDidMount() {
    this.updateMenuListClassName();
  }
  public componentDidUpdate() {
    this.updateMenuListClassName();
  }

  public updateMenuListClassName() {
    const dom = ReactDOM.findDOMNode(this);
    if (dom && typeof dom !== 'string') {
      const list = (dom as HTMLElement).getElementsByClassName('br-select__menu-list')[0];
      if (list) {
        const className = list.className;
        const newClassName = classNames(className, {
          'br-select__menu-list--scroll br-scroll': isScrollBarVisible(list as HTMLElement),
        });
        list.className = newClassName;
      }
    }
  }

  public render() {
    const { onFilterChange, options, onInputClick, onItemClick, value, type } = this.props;
    let searchElement;
    if (type === 'search') {
      searchElement = <div className="br-select__search-box">
        <Input
          small
          onClick={onInputClick}
          autoFocus
          icon={<Icon type="search" size={12} color="#888" />}
          onChange={(e) => onFilterChange((e.target as { value: string }).value)}
        />
      </div>;
    }

    // TODO: 空数据时，需要文本提示
    let items: React.ReactNode = this.props.emptyTips ||
      <li className="br-select__menu-item br-select__menu-item--disabled">暂无数据</li>;

    if (options.length) {
      items = options.map((option, index) => {
        const isSelected = value.find((val) => val.value === option.value);
        return (
          <li key={index}
            className={classNames('br-select__menu-item', {
              'br-select__menu-item--selected': isSelected as boolean,
              'br-select__menu-item--disabled': option.disabled,
            })}
            onClick={(e) => onItemClick(option, index)}
          >
            {option.label}
          </li>
        );
      });
    }

    return (
      <div className="br-select__menu" onClick={onInputClick}>
        {searchElement}
        <ul className="br-select__menu-list">
          {items}
        </ul>
      </div>
    );
  }
}
